package com.wnxy.admin.mqtt;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.CharsetUtil;
import com.alibaba.fastjson.JSON;
import com.wnxy.admin.common.mqtt.MqttConfiguration;
import com.wnxy.admin.common.mqtt.MyMQTTClient;
import com.wnxy.admin.common.util.SpringUtils;
import com.wnxy.admin.controller.OrderController;
import com.wnxy.admin.dto.OrderDto;
import com.wnxy.admin.service.IOrderService;
import org.eclipse.paho.client.mqttv3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * @author (^･ｪ･^)Cat~
 * @date 2023-12-05 19:24
 */
public class MyMQTTCallback implements MqttCallbackExtended {

    //手动注入
    private MqttConfiguration mqttConfiguration = SpringUtils.getBean(MqttConfiguration.class);

    private static final Logger log = LoggerFactory.getLogger(MyMQTTCallback.class);

    private MyMQTTClient myMQTTClient;

    private IOrderService orderServiceImpl;

    public MyMQTTCallback(MyMQTTClient myMQTTClient) {
        this.myMQTTClient = myMQTTClient;
    }

    /**
     * 丢失连接,可在这里做重连
     * 只会调用一次
     *
     * @param throwable
     */
    @Override
    public void connectionLost(Throwable throwable) {
        log.warn("mqtt connectionLost 连接断开，5S之后尝试重连: {}", throwable.getMessage());
        long reconnectTimes = 1;
        while (true) {
            try {
                if (MyMQTTClient.getClient().isConnected()) {
                    // 判断已经重新连接成功,需要重新订阅主题 可以在这个if里面订阅主题  或者 connectComplete（方法里面）
                    log.warn("mqtt reconnect success end  重新连接  重新订阅成功");
                    return;
                }
                reconnectTimes+=1;
                log.warn("mqtt reconnect times = {} try again...  mqtt重新连接时间 {}", reconnectTimes, reconnectTimes);
                MyMQTTClient.getClient().reconnect();
            } catch (MqttException e) {
                log.warn("mqtt断连异常", e);
            }
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e1) {
                log.warn("━((*′д｀)爻(′д｀*))━!!!!");
            }
        }
    }

    /**
     * @param topic
     * @param mqttMessage
     * @throws Exception
     * subscribe后得到的消息会执行到这里面
     */
    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
        log.info("接收消息主题 : {}，接收消息内容 : {}", topic, new String(mqttMessage.getPayload()));
        // 发布消息主题Command
        if (topic.equals(mqttConfiguration.getTopic1())){
            Map maps = (Map) JSON.parse(new String(mqttMessage.getPayload(), CharsetUtil.UTF_8));
            // 业务接口
            System.out.println("发布消息主题Maps" + "name");
            maps.forEach((key, value) -> System.out.println("Key: " + key + " - Value:" + value));
        }

        // 【Order模块】接收业务主题iot/k-on
        if (topic.equals(mqttConfiguration.getTopic2())){
            Map maps = (Map)JSON.parse(new String(mqttMessage.getPayload(), CharsetUtil.UTF_8));

            OrderDto orderDto = new OrderDto();
            BeanUtil.fillBeanWithMap(maps, orderDto, false, true);

            // 业务接口
            System.out.println("接收业务主题<(￣︶￣)↗[GO!]" + maps.get("name"));
            maps.forEach((key, value) -> System.out.println("Key: " + key + " - Value:" + value));
            orderDto.setPileId(0);
            orderDto.setCardNumber("RD");
            // 打印OrderDto对象
            System.out.println("OrderDto: " + orderDto);
            /*orderServiceImpl.saveOrderDto(orderDto);*/
        }

        // 接收 - 预警主题connect/prediction | 设备主题connect/plie
        if (topic.equals("connect/plie")){
            Map maps = (Map) JSON.parse(new String(mqttMessage.getPayload(), CharsetUtil.UTF_8));
            // 业务接口
            System.out.println("接收设备主题" + maps.get("name"));
            maps.forEach((key, value) -> System.out.println("Key: " + key + " - Value:" + value));
        }
        if (topic.equals("connect/prediction")){
            Map maps = (Map) JSON.parse(new String(mqttMessage.getPayload(), CharsetUtil.UTF_8));
            // 业务接口
            System.out.println("接收预警主题(。﹏。*)" + maps.get("name"));
            maps.forEach((key, value) -> System.out.println("Key: " + key + " - Value:" + value));
        }
    }


    /**
     * 连接成功后回调 -> 可以在这个方法执行,订阅主题. 生成Bean的MqttConfiguration方法中订阅主题(出现Bug)
     * 重新连接后 -> 主题也需要再次订阅,将重新订阅主题放在连接成功后的回调.比较合理
     * @param reconnect
     * @param serverURI
     */
    @Override
    public  void  connectComplete(boolean reconnect,String serverURI){
        /*log.info("MQTT 连接成功，连接方式：{}",reconnect?"重连":"直连" + serverURI);*/
        //订阅主题
        myMQTTClient.subscribe(mqttConfiguration.getTopic1(), 0);
        myMQTTClient.subscribe(mqttConfiguration.getTopic2(), 1);
       /* myMQTTClient.subscribe(mqttConfiguration.getTopic3(), 0);
        myMQTTClient.subscribe(mqttConfiguration.getTopic4(), 0);*/
    }

    /**
     * 消息到达后
     * subscribe后，执行的回调函数
     *
     * @param mqttMessage
     * @throws Exception
     */
    /**
     * publish后，配送完成后回调的方法
     * @param iMqttDeliveryToken
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        /*log.info("==========deliveryComplete={}==========", iMqttDeliveryToken.isComplete());*/
    }
}


